<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL 绘制一个渐变色</title>
</head>

<body>
    <canvas id="webglCanvas" width="400" height="400"></canvas>
    <script>
        const canvas = document.getElementById('webglCanvas');
        const gl = canvas.getContext('webgl');


        // 顶点着色器源代码  
        const vertexShaderSource = `  
            attribute vec2 a_position;  
        
            void main() {  
                gl_Position = vec4(a_position, 0.0, 1.0);  
            }  
        `;

        // 片段着色器源代码  
        const fragmentShaderSource = `
        precision mediump float;  
        uniform vec2 u_resolution;
        uniform vec2 u_rectSize;   // 矩形大小，例如 vec2(200.0, 200.0)  
        uniform vec2 u_rectPos; 
  
        void main() {  
            // 计算片元相对于矩形原点的位置  
            vec2 fragPosRect = gl_FragCoord.xy - u_rectPos;  
        
            // 判断片元是否在矩形内  
            bool insideRect = all(greaterThanEqual(fragPosRect, vec2(0.0))) && all(lessThan(fragPosRect, u_rectSize));  
        
            vec3 color = vec3(0.0, 0.0, 0.0); // 初始化为黑色或其他背景色  
            if (insideRect) {  
                // 计算片元在矩形内的归一化位置（0.0 到 1.0）  
                float x = fragPosRect.x / u_rectSize.x;  
                color = vec3(1.0 - x, 0.0, x);  
            }  
        
            gl_FragColor = vec4(color, 1.0);  
        }
        `;

        // 创建着色器程序  
        function createShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);

            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                console.error('Error compiling shader:', gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
            }

            return shader;
        }

        // 创建并链接着色器程序  
        function createProgram(gl, vertexShader, fragmentShader) {
            const program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);

            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                console.error('Error linking program:', gl.getProgramInfoLog(program));
                gl.deleteProgram(program);
                return null;
            }

            return program;
        }

        // 设置顶点数据  
        const vertices = new Float32Array([
            -0.5, -0.5, // 左下角  
            0.5, -0.5, // 右下角  
            -0.5, 0.5,   // 顶部 
            0.5, 0.5   // 顶部  

        ]);

        // 创建顶点缓冲区  
        const vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        // 获取顶点着色器中的a_position属性位置  
        const program = createProgram(gl, createShader(gl, gl.VERTEX_SHADER, vertexShaderSource), createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource));
        gl.useProgram(program);

        const aPosition = gl.getAttribLocation(program, 'a_position');
        gl.enableVertexAttribArray(aPosition);
        gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);

        let u_resolution = gl.getUniformLocation(program, 'u_resolution');
        gl.uniform2fv(u_resolution, [400.0, 400.0]);

        let u_rectSize = gl.getUniformLocation(program, 'u_rectSize');
        gl.uniform2fv(u_rectSize, [200.0, 200.0]);

        let u_rectPos = gl.getUniformLocation(program, 'u_rectPos');
        gl.uniform2fv(u_rectPos, [100.0, 100.0]);

        // 清除画布并绘制三角形  
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertices.length);
    </script>
</body>

</html>